﻿"use strict";
function generateRandomId(){
	return Math.floor(Math.random()*123456789);
}
function InstrumentSample(key) {
	var me = this;
	me.correction = 0;
	me.startLoop = 0;
	me.endLoop = 0;
	me.float32Array = null;
	me.key = key;
	me.color=0xff00ff;
	me.volume=1.0;
	me.midi=0;
	me.load = function () {
		me.parse();
	};
	me.parse = function () {
		var p0 = me.key.split(".");
		var p1 = p0[0].split("/");
		var p2 = p1[p1.length - 1];
		var p3 = p2.split("_");
		me.correction = 1.0 * p3[1];
		var p4 = p3[2].split("-");
		me.startLoop = 1.0 * p4[0];
		me.endLoop = 1.0 * p4[1];
	};
	me.parse();
	return me;
}
function DrumSample(key) {
	var me = this;
	me.correction = 0;
	me.startLoop = 0;
	me.endLoop = 0;
	me.float32Array = null;
	me.key = key;
	me.volume=1.0;
	me.midi=0;
	me.load = function () {
		me.parse();
	};
	me.parse = function () {//drums/000/Chaos_128/054_-5400.019
		var p0 = me.key.split(".");
		var p1 = p0[0].split("/");
		var p2 = p1[p1.length - 1];
		var p3 = p2.split("_");
		me.midi= 1.0 * p3[0];
		me.correction = 1.0 * p3[1];
	};
	me.parse();
	console.log(me);
	return me;
}
function CacheStore() {
	var me = this;
	me.instrumentFolder = "http://www.javafx.me/extracted16/";
	me.drumFolder = "http://www.javafx.me/extracted16/";
	//me.values = [];
	me.samples = [];
	//me.instruments = [];
	me.loadInstruments = function (instrumentSamples, afterError, beforeProgress, afterSuccess) {
		var found = false;
		for (var i = 0; i < instrumentSamples.length; i++) {
			if (instrumentSamples[i].float32Array == null) {
				found=true;
				beforeProgress(instrumentSamples[i]);
				//console.log(me.instrumentFolder, instrumentSamples[i]);
				me.fetchSample(me.instrumentFolder + instrumentSamples[i].key, instrumentSamples[i].key//
				, function (float32Array) {
					instrumentSamples[i].float32Array = float32Array;
					me.loadInstruments(instrumentSamples, afterError, beforeProgress, afterSuccess);
				}, function () {
					console.log("ops");
				});
				break;
			}
		}
		if (!found) {
			afterSuccess();
		}
	};
	me.drop = function (key) {
		window.localStorage.removeItem(key);
	};
	me.arrayBufferToBase64 = function (arrayBuffer) {
		var text = '';
		var uint8Array = new Uint8Array(arrayBuffer);
		var byteLength = uint8Array.byteLength;
		for (var i = 0; i < byteLength; i++) {
			text = text + String.fromCharCode(uint8Array[i]);
		}
		return window.btoa(text);
	};
	me.base64ToArrayBuffer = function (base64) {
		var text = window.atob(base64);
		var length = text.length;
		var uint8Array = new Uint8Array(length);
		for (var i = 0; i < length; i++) {
			var charCode = text.charCodeAt(i);
			uint8Array.set([charCode], i);
		}
		return uint8Array.buffer;
	};
	/*
	me.findInMemory = function (key) {
	var value = me.findValue(key);
	if (value != null) {
	return value.arrayBuffer;
	}
	return null;
	};*/
	me.findSampleInMemory = function (key) {
		var s = me.findSampleValue(key);
		if (s != null) {
			return s.float32Array;
		}
		return null;
	};
	/*
	me.findValue = function (key) {
	for (var i = 0; i < me.values.length; i++) {
	if (me.values[i].key == key) {
	return me.values[i];
	}
	}
	return null;
	};*/
	me.findSampleValue = function (key) {
		for (var i = 0; i < me.samples.length; i++) {
			if (me.samples[i].key == key) {
				return me.samples[i];
			}
		}
		return null;
	};
	/*
	me.findInCache = function (key) {
	var b64 = window.localStorage.getItem(key);
	if (b64 != null) {
	var arrayBuffer = me.base64ToArrayBuffer(b64);
	var value = me.findValue(key);
	if (value != null) {
	value.arrayBuffer = arrayBuffer;
	} else {
	var v = {
	key : key,
	arrayBuffer : arrayBuffer
	};
	me.values.push(v);
	console.log("found cache " + key);
	return arrayBuffer;
	}
	}
	return null;
	};*/
	me.findSampleInCache = function (key) {
		var b64 = window.localStorage.getItem(key);
		if (b64 != null) {
			var arrayBuffer = me.base64ToArrayBuffer(b64);
			var float32Array = new Float32Array(arrayBuffer);
			var value = me.findSampleValue(key);
			if (value != null) {
				value.float32Array = float32Array;
			} else {
				var v = {
					key : key,
					float32Array : float32Array
				};
				me.samples.push(v);
				console.log("found cache " + key);
				return float32Array;
			}
		}
		return null;
	};
	/*
	me.fetch = function (url, key, afterSuccess, afterError) {
	var inMemory = me.findInMemory(key);
	if (inMemory == null) {
	var inCache = me.findInCache(key);
	if (inCache == null) {
	httpGETArray(url, function (arrayBuffer) {
	var v = {
	key : key,
	arrayBuffer : arrayBuffer
	};
	me.values.push(v);
	var b64 = me.arrayBufferToBase64(arrayBuffer);
	window.localStorage.setItem(key, b64);
	console.log("download " + key);
	afterSuccess(arrayBuffer);
	}, function (xmlHttpRequest) {
	console.log("afterStatus", xmlHttpRequest);
	afterError();
	}, function (xmlHttpRequestProgressEvent) {
	console.log("afterError", xmlHttpRequestProgressEvent);
	afterError();
	});
	} else {
	afterSuccess(inCache);
	}
	} else {
	afterSuccess(inMemory);
	}
	};*/
	me.fetchSample = function (url, key, afterSuccess, afterError) {
		var inMemory = me.findSampleInMemory(key);
		if (inMemory == null) {
			var inCache = me.findSampleInCache(key);
			if (inCache == null) {
				httpGETArray(url, function (arrayBuffer) {
					var float32Array = new Float32Array(arrayBuffer.byteLength / 2);
					var uint8Array = new Uint8Array(arrayBuffer);
					for (var i = 0; i < float32Array.length; i++) {
						var v = 256 * uint8Array[i * 2 + 1] + uint8Array[i * 2 + 0];
						if (v >= 128 * 256) {
							v = v - 256 * 256;
						}
						float32Array[i] = 256 * (Math.floor(v / (256 * 256) / 256));
						float32Array[i] = v / (256 * 256);
					}
					var v = {
						key : key,
						float32Array : float32Array
					};
					me.samples.push(v);
					var b64 = me.arrayBufferToBase64(float32Array.buffer);
					window.localStorage.setItem(key, b64);
					console.log("downloaded " + key);
					afterSuccess(float32Array);
				}, function (xmlHttpRequest) {
					console.log("afterStatus", xmlHttpRequest);
					afterError();
				}, function (xmlHttpRequestProgressEvent) {
					console.log("afterError", xmlHttpRequestProgressEvent);
					afterError();
				});
			} else {
				afterSuccess(inCache);
			}
		} else {
			afterSuccess(inMemory);
		}
	};
	return me;
}
